-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
soroban-rpc: simulateTransaction: automatically detect ledger entries which require restoring #865
Conversation
6cf6d6f
to
fafe104
Compare
… which require restoring This change incorporates two new fields to the simulateTransactionResponse: ``` PreRestoreTransactionData string `json:"preRestoreTransactionData,omitempty"` // SorobanTransactionData XDR in base64 PreRestoreMinResourceFee int64 `json:"preRestoreMinResourceFee,omitempty"` ``` When preflighting an InvokeHostFunction operation, soroban-rpc will now detect ledger entries which require restoring prior to the invocation for it to succeed. If any such entries are detected, the simulateTransaction response will provide the Soroban Transaction Data and minimum resource fee needed to restore those entries. The user is then now expected to: 1. Submit a RestoreFootprint operation using the new fields above, if present. 2. Submit the InvokeHostFunction operation normally.
fafe104
to
ebe29e4
Compare
@dmkozh does something like state_expiration.rs already exist? I figure you need something like that upstream. Otherwise, it may make sense to place it in the env library if you find it appropriate. |
// Wait for expiration again and check the pre-restore field when trying to exec the contract again | ||
waitForExpiration() | ||
|
||
simulationResult := simulateTransactionFromTxParams(t, client, invokeIncPresistentEntryParams) | ||
assert.NotZero(t, simulationResult.PreRestoreTransactionData) | ||
assert.NotZero(t, simulationResult.PreRestoreMinResourceFee) | ||
|
||
params = preflightTransactionParamsLocally(t, | ||
txnbuild.TransactionParams{ | ||
SourceAccount: &account, | ||
IncrementSequenceNum: true, | ||
Operations: []txnbuild.Operation{ | ||
&txnbuild.RestoreFootprint{}, | ||
}, | ||
Preconditions: txnbuild.Preconditions{ | ||
TimeBounds: txnbuild.NewInfiniteTimeout(), | ||
}, | ||
}, | ||
methods.SimulateTransactionResponse{ | ||
TransactionData: simulationResult.PreRestoreTransactionData, | ||
MinResourceFee: simulationResult.PreRestoreMinResourceFee, | ||
}, | ||
) | ||
tx, err = txnbuild.NewTransaction(params) | ||
assert.NoError(t, err) | ||
sendSuccessfulTransaction(t, client, sourceAccount, tx) | ||
|
||
// Finally, we should be able to send the inc host function invocation now that we | ||
// have pre-restored the entries | ||
params = preflightTransactionParamsLocally(t, invokeIncPresistentEntryParams, simulationResult) | ||
tx, err = txnbuild.NewTransaction(params) | ||
assert.NoError(t, err) | ||
sendSuccessfulTransaction(t, client, sourceAccount, tx) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Shaptic here's an example of how to use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! This means the flow is something like:
result = simulateTransaction(invoke)
if result.PreRestoreTransactionData != undefined:
submitTransaction(restore, transactionData=result.PreRestoreTransactionData)
result = simulateTransaction(invoke)
submitTransaction(invoke, transactionData=result.transactionData)
Correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, assuming you somehow also use the minfee too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, you don't need the second simulation
result = simulateTransaction(invoke)
if result.PreRestoreTransactionData != undefined:
submitTransaction(restore, transactionData=result.PreRestoreTransactionData)
submitTransaction(invoke, transactionData=result.transactionData)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Shaptic did you see my udpate above? You don't need to re-run the transaction simulation
To me, |
@willemneal we should probably use this in the cli once merged |
@Shaptic you have an example of how to use this at
No strong opinions here. |
thinking about that further, I think that what I'd like to see if I were in @Shaptic 's seat is the following:
where the restorePreamble is defined as
|
@tsachiherman from a client perspective, having one omittable structure is better than two, so yes, I agree - I like encapsulating it into a structure like this. Of course we could have said "zero or both of these are present," but "zero or one" is much better! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you rock 🎸
this LGTM as-is but I’d prefer the schema Tsachi outlined
sure |
Co-authored-by: George <Shaptic@users.noreply.github.com>
This change incorporates two new fields to simulateTransaction's Response:
When preflighting an InvokeHostFunction operation, soroban-rpc will now detect ledger entries which require restoring prior to the invocation for it to succeed.
If any such entries are detected, the simulateTransaction response will provide the Soroban Transaction Data and minimum resource fee needed to restore those entries.
The user is then now expected to:
Closes #803